package cn.anosi.utils;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateNotFoundException;

/**
 * 代码生成器
 * @author admin
 *
 */
public class GenUtils {
	//项目根目录
	private final static String root = System.getProperty("user.dir");
	//模板目录
	private final static String tempDir = root + "/sssp/src/main/resources/template";
	
	private static Configuration configuration;
	
	private  static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");	
	
	static{
		configuration = new Configuration(Configuration.getVersion());
		//指定模板路径
		try {
			configuration.setDirectoryForTemplateLoading(new File(tempDir));
		} catch (IOException e) {
			e.printStackTrace();
		}
		configuration.setDefaultEncoding("utf-8");
		
		//全局共享变量
		try {
			configuration.setSharedVariable("auth", "刘彦硕");
			configuration.setSharedVariable("date", sdf.format(new Date()));
		} catch (TemplateModelException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 生成文件
	 * @param templateName 模板名称
	 * @param fileName  文件全路径名
	 * @param map  参数
	 * @return
	 * @throws TemplateNotFoundException
	 * @throws MalformedTemplateNameException
	 * @throws ParseException
	 * @throws IOException
	 * @throws TemplateException
	 */
	public static boolean gen(String templateName, String fileName, Map map) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException{
		Template template = configuration.getTemplate(templateName);
		File file = new File(fileName);
		Writer out = new FileWriter(file);
		template.process(map, out);
		out.flush();
		out.close();
		return file.exists();
	}
	
	/**
	 * 生成entity
	 * @param entityPackage
	 * @param entity
	 * @param description
	 * @param tableName
	 * @param list
	 * @return
	 * @throws TemplateNotFoundException
	 * @throws MalformedTemplateNameException
	 * @throws ParseException
	 * @throws IOException
	 * @throws TemplateException
	 */
	public static boolean genEntity(String entityPackage, String entity,String description, String tableName, List<String[]> list) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException{
		Map<String, Object> map = new HashMap<String, Object>();
		
		map.put("package", entityPackage);
		map.put("entity", entity);
		map.put("description", description);
		map.put("tableName", tableName);
		
		//设置属性
		map.put("list", list);
		
		String outDir = root + "/sssp/src/main/java/" + entityPackage.replaceAll("\\.", "/") + "/";
		File parent = new File(outDir);
		parent.mkdirs();
		String fileName = outDir + entity +".java";
		return gen("entity.ftl", fileName, map);
	}
	
	/**
	 * 生成repository
	 * @param entityPackage
	 * @param repositoryPackage
	 * @param entity
	 * @return
	 * @throws TemplateNotFoundException
	 * @throws MalformedTemplateNameException
	 * @throws ParseException
	 * @throws IOException
	 * @throws TemplateException
	 */
	public static boolean genRepository(String entityPackage, String repositoryPackage, String entity) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException{
		Map<String, Object> map = new HashMap<String, Object>();
		
		map.put("entityPackage", entityPackage);
		map.put("entity", entity);
		map.put("repositoryPackage", repositoryPackage);
		
		String outDir = root + "/sssp/src/main/java/" + repositoryPackage.replaceAll("\\.", "/") + "/";
		File parent = new File(outDir);
		parent.mkdirs();
		String fileName = outDir + entity + "Repository" +".java";
		return gen("repository.ftl", fileName, map);
	}
	
	/**
	 * 生成service
	 * @param entityPackage
	 * @param repositoryPackage
	 * @param entity
	 * @param servicePackage
	 * @return
	 * @throws TemplateNotFoundException
	 * @throws MalformedTemplateNameException
	 * @throws ParseException
	 * @throws IOException
	 * @throws TemplateException
	 */
	private static boolean genService(String entityPackage, String repositoryPackage, String entity,
			String servicePackage) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
		Map<String, Object> map = new HashMap<String, Object>();
		
		map.put("entityPackage", entityPackage);
		map.put("entity", entity);
		map.put("repositoryPackage", repositoryPackage);
		map.put("servicePackage", servicePackage);
		
		String outDir = root + "/sssp/src/main/java/" + servicePackage.replaceAll("\\.", "/") + "/";
		File parent = new File(outDir);
		parent.mkdirs();
		String fileName = outDir + entity + "Service" +".java";
		return gen("service.ftl", fileName, map);
	}
	
	/**
	 * 生成controller
	 * @param entityPackage
	 * @param repositoryPackage
	 * @param entity
	 * @param servicePackage
	 * @param controllerPackage
	 * @param list
	 * @return
	 * @throws TemplateNotFoundException
	 * @throws MalformedTemplateNameException
	 * @throws ParseException
	 * @throws IOException
	 * @throws TemplateException
	 */
	private static boolean genController(String entityPackage, String repositoryPackage, String entity,
			String servicePackage, String controllerPackage, List<String[]> list, String description) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
		Map<String, Object> map = new HashMap<String, Object>();
		
		map.put("entityPackage", entityPackage);
		map.put("entity", entity);
		map.put("repositoryPackage", repositoryPackage);
		map.put("servicePackage", servicePackage);
		map.put("controllerPackage", controllerPackage);
		map.put("list", list);
		map.put("description", description);
		
		String outDir = root + "/sssp/src/main/java/" + controllerPackage.replaceAll("\\.", "/") + "/";
		File parent = new File(outDir);
		parent.mkdirs();
		String fileName = outDir + entity + "Controller" +".java";
		return gen("controller.ftl", fileName, map);
	}
	
	
	public static void main(String[] args) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException{
		//==================== 必须填写开始 ============= //
		//实体类包名
		String entityPackage = "cn.anosi.entity.test2";
		//实体类名
		String entity = "Product";
		//描述
		String description = "产品";
		//表名
		String tableName = "product";
		//实体类的属性
		List<String[]> list = new ArrayList<String[]>();
		list.add(new String[]{"String","name","产品名称"});
		list.add(new String[]{"int","price","单价"});
		//list.add(new String[]{"String","no","学号"});
		
		//==================== 必须填写结束 ============= //
		
		
		//==================== 计算开始 ============= //
		String repositoryPackage = entityPackage.replace("entity", "repository");
		String servicePackage = entityPackage.replace("entity", "service");
		String controllerPackage = entityPackage.replace("entity", "controller");
		//==================== 计算结束 ============= //
		
		
		
		//==================== 生成开始  ============= //
		boolean result = false;
		result = genEntity(entityPackage, entity, description, tableName, list);
		if(result){
			entityPackage += "." + entity;
			System.out.println("实体类生成成功");
			
			result = genRepository(entityPackage, repositoryPackage, entity);
			if(result){
				System.out.println("repository生成成功");
				repositoryPackage += "." + entity + "Repository";
				result = genService(entityPackage, repositoryPackage, entity, servicePackage);
				
				if(result){
					System.out.println("service生成成功");
					servicePackage += "." + entity + "Service";
					
					result = genController(entityPackage, repositoryPackage, entity, servicePackage,controllerPackage, list, description);
					
					if(result){
						System.out.println("controller 生成成功");
						
						/*int noSort = list.size() + 4;
						result = genList(entity, description, list, noSort);
						
						if(result){
							System.out.println("list 生成成功");
							result = genAdd(entity, list);
							
							if(result){
								System.out.println("add 生成成功");
								result = genEdit(entity, list);
								
								if(result){
									System.out.println("edit 生成成功");
								}
							}
						}*/
					}
				}
			}
		}
		//==================== 生成结束  ============= //
	}

	private static boolean genEdit(String entity, List<String[]> list) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("entity", entity);
		map.put("list", list);
		
		String outDir = root + "/src/main/webapp/WEB-INF/ftl/" + entity.substring(0, 1).toLowerCase() + entity.substring(1) + "/";
		File parent = new File(outDir);
		parent.mkdirs();
		String fileName = outDir +"edit.html";
		return gen("edit.ftl", fileName, map);
	}

	private static boolean genAdd(String entity, List<String[]> list) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("entity", entity);
		map.put("list", list);
		
		String outDir = root + "/src/main/webapp/WEB-INF/ftl/" + entity.substring(0, 1).toLowerCase() + entity.substring(1) + "/";
		File parent = new File(outDir);
		parent.mkdirs();
		String fileName = outDir +"add.html";
		return gen("add.ftl", fileName, map);
	}

	private static boolean genList(String entity, String description, List<String[]> list, int noSort) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("description", description);
		map.put("entity", entity);
		map.put("noSort", noSort);
		map.put("list", list);
		
		String outDir = root + "/src/main/webapp/WEB-INF/ftl/" + entity.substring(0, 1).toLowerCase() + entity.substring(1) + "/";
		File parent = new File(outDir);
		parent.mkdirs();
		String fileName = outDir +"list.html";
		return gen("list.ftl", fileName, map);
	}

	
}
